import wx

from .xrc.login_xrc import xrcLogin

class LoginWindow(xrcLogin):
    """Remote connection settings window."""

    errorColor = wx.Colour(255, 0, 0)

    _textboxes = ()
    _loginSection = "Login Data"

    def __init__(self, parent, application):
        self._app = application
        super(LoginWindow, self).__init__(parent)
        self.loadSessions()
        self._textboxes = (
            self.hostAddress,
            self.hostPort,
            self.username,
            self.password,
            self.newSessionName,
        )

    def loadSessions(self):
        """Load session list from application config."""
        self._section = self._app.getConfigSection(self._loginSection, {})
        self._sessions = self._section.get("sessions", [{
            "name": "Freerunner generic",
            "host": "192.168.0.202",
            "port": 22,
            "user": "root",
            "password": "",
        }])
        self.setSessionList()
        _lastSession = self._section.get(
            "last session", "Freerunner generic")
        if _lastSession:
            _pos = 0
            for (_num, _ses) in enumerate(self._sessions):
                if _ses["name"] == _lastSession:
                    _pos = _num + 1
            self.sessionBox.SetSelection(_pos)
            if _pos > 0:
                self.loadSession()
        else:
            self.sessionBox.SetSelection(0)
        self.updateControls()

    def setSessionList(self):
        """Populate session dropdown box."""
        self.sessionBox.Clear()
        # first selection always comes 'New session'
        self.sessionBox.Append("New session")
        for _ses in self._sessions:
            self.sessionBox.Append(_ses["name"])

    def saveSessions(self):
        """Save sessin data to application config."""
        if self.isNewSession():
            if self.saveSession.IsChecked():
                self._section["last session"] = \
                    self.newSessionName.Value
            else:
                self._section.pop("last session", None)
        else:
            self._section["last session"] = \
                self._sessions[self.getSessionPos()]["name"]
        self._sessions.sort(key=lambda el: el["name"])
        self._section["sessions"] = self._sessions
        self._app.setConfigSection(self._loginSection, self._section)

    def terminate(self):
        """Called when this form is being closed."""
        self.saveSessions()
        self.Destroy()

    def isNewSession(self):
        """Return True if selected session is 'New session'."""
        return self.sessionBox.GetSelection() == 0

    def getSessionPos(self):
        """Return selected session data position in sessin array."""
        assert self.sessionBox.GetSelection() > 0
        return self.sessionBox.GetSelection() - 1

    def updateControls(self):
        """Pupulate GUI controls with session data."""
        self.savePassword.Enabled = self.saveSession.IsChecked()
        self.newSessionName.Enabled = \
            self.isNewSession() and self.saveSession.IsChecked()
        self.deleteButton.Enabled = not self.isNewSession()
        for _obj in self._textboxes:
            self.stripValue(_obj)
            _obj.SetBackgroundColour(None)


    def errorOn(self, control):
        """Show user that something suspicions \
        is happening with given control.

        """
        control.SetBackgroundColour(self.errorColor)
        control.Refresh()
        control.SetFocus()

    def stripValue(self, control):
        """remove spaces from given control value."""
        control.Value = control.Value.strip()
        control.Refresh()

    def valid(self):
        """Return 'True' if entered session data seems to be valid.

        (Also show to user on errorous control).

        """
        if self.isNewSession():
            _val = self.newSessionName.Value
            _nameBusy = (_s["name"] == _val for _s in self._sessions)
            if not _val or any(_nameBusy):
                self.errorOn(self.newSessionName)
                return False
        if not self.hostAddress.Value:
            self.errorOn(self.hostAddress)
            return False
        if not self.hostPort.Value.isdigit():
            self.errorOn(self.hostPort)
            return False
        if not self.username.Value:
            self.errorOn(self.hostPort)
            return False
        # allow for password to be blank
        # (means "not checking it" right now)
        return True

    def loadSession(self):
        """Load selected session data to GUI."""
        _session = self._sessions[self.getSessionPos()]
        self.hostAddress.Value = _session["host"]
        self.hostPort.Value = str(_session["port"])
        self.username.Value = _session["user"]
        self.password.Value = _session.get("password", "")
        self.saveSession.Value = True
        self.savePassword.Enabled = True
        self.savePassword.Value = bool(_session.has_key("password"))

    ## Handlers

    def OnCombobox_sessionBox(self, evt):
        """The session was chosen."""
        self.updateControls()
        if self.isNewSession():
            for _obj in self._textboxes:
                _obj.Clear()
            self.saveSession.Value = True
            self.savePassword.Value = False
            self.savePassword.Enabled = True
        else:
            self.loadSession()

    def OnCheckbox_saveSession(self, evt):
        """User changed 'I want to save session' checkbox value."""
        self.updateControls()

    def OnClose(self, evt):
        """wx.EVT_CLOSE"""
        self.terminate()

    def OnButton_deleteButton(self, evt):
        """User clicked 'Delete' button."""
        assert not self.isNewSession()
        _lastPos = self.getSessionPos()
        self._sessions.pop(_lastPos)
        self.setSessionList()
        self.sessionBox.SetSelection(min(
            _lastPos, len(self._sessions)-1))
        self.updateControls()

    def OnButton_OkButton(self, evt):
        """User clicked 'OK' button."""
        self.updateControls()
        if not self.valid():
            return
        _session = {
            "host": self.hostAddress.Value,
            "port": int(self.hostPort.Value),
            "user": self.username.Value,
            "password": self.password.Value,
        }
        if self.saveSession.Value:
            _ss = _session.copy()
            if not self.savePassword.Value:
                _ss.pop("password")
            if self.isNewSession():
                # "New session"
                _ss["name"] = self.newSessionName.Value
                self._sessions.append(_ss)
            else:
                self._sessions[self.getSessionPos()].update(_ss)
        self._app.setActiveSession(_session)
        self.terminate()

# vim: set sts=4 sw=4 et :
